package com.rabbit.videoplayer.widget.player

import android.content.Context
import android.graphics.Bitmap
import android.graphics.Color
import android.util.Log
import android.view.Surface
import android.view.View
import android.widget.FrameLayout
import com.aliyun.player.AliPlayer
import com.aliyun.player.AliPlayerFactory
import com.aliyun.player.AliPlayerGlobalSettings
import com.aliyun.player.IPlayer
import com.aliyun.player.IPlayer.MirrorMode
import com.aliyun.player.IPlayer.OnSnapShotListener
import com.aliyun.player.IPlayer.OnSubtitleDisplayListener
import com.aliyun.player.IPlayer.OnTrackChangedListener
import com.aliyun.player.IPlayer.OnTrackReadyListener
import com.aliyun.player.IPlayer.RotateMode
import com.aliyun.player.IPlayer.ScaleMode
import com.aliyun.player.IPlayer.SeekMode
import com.aliyun.player.bean.ErrorInfo
import com.aliyun.player.bean.InfoBean
import com.aliyun.player.bean.InfoCode
import com.aliyun.player.nativeclass.MediaInfo
import com.aliyun.player.nativeclass.PlayerConfig
import com.aliyun.player.nativeclass.TrackInfo
import com.aliyun.player.source.UrlSource
import com.rabbit.videoplayer.IMixPlayer
import com.rabbit.videoplayer.IRenderView
import com.rabbit.videoplayer.IRenderView.IRenderCallback
import com.rabbit.videoplayer.surface.SurfaceRenderView
import com.rabbit.videoplayer.surface.TextureRenderView
import com.rabbit.videoplayer.listener.player.*
import com.rabbit.videoplayer.response.PlayerType
import com.rabbit.videoplayer.tools.Constants
import com.rabbit.videoplayer.tools.PathUtils
import com.rabbit.videoplayer.tools.VideoPlayerSPUtil
import java.io.File
import java.lang.ref.WeakReference

internal class AliyunRenderView(context: Context) : FrameLayout(context), IMixPlayer {

    private var mOnVideoStreamTrackTypeListener: OnVideoStreamTrackTypeListener? = null
    private var mOnPreparedListener: OnPreparedListener? = null
    private var mOnVideoRenderedListener: IPlayer.OnVideoRenderedListener? = null
    private var mOnRenderingStartListener: OnRenderingStartListener? = null
    private var mOnStateChangedListener: OnStateChangedListener? = null
    private var mOnVideoSizeChangedListener: OnVideoSizeChangedListener? = null
    private var mOnTrackReadyListener: OnTrackReadyListener? = null
    private var mOnLoadingStatusListener: OnLoadingStatusListener? = null
    private var mOnSnapShotListener: OnSnapShotListener? = null
    private var mOnCompletionListener: OnCompletionListener? = null
    private var mOnSeekCompleteListener: IPlayer.OnSeekCompleteListener? = null
    private var mOnTrackChangedListener: OnTrackChangedListener? = null
    private var mOnErrorListener: OnErrorListener? = null
    private var mOnSubtitleDisplayListener: OnSubtitleDisplayListener? = null
    private var mOnInfoListener: OnInfoListener? = null


    /**
     * 真正的播放器实例对象
     */
    private lateinit var aliPlayer: AliPlayer

    /**
     * Surface
     */
    private var mIRenderView: IRenderView? = null

    /**
     * 起播时间
     */
    private var startPosition: Long = -1L

    /**
     * 当前进度
     */
    private var currentPosition: Long = 0L

    private var bufferedPosition: Long = 0L
    private var currentDownloadSpeed: Long = 0L


    /**
     * 根据回调返回的播放器状态;
     * idle: 0
     * initalized: 1
     * prepared: 2
     * started: 3
     * paused: 4
     * stopped: 5
     * completion: 6
     * error: 7
     */
    private var status = 0


    override fun initPlayer(context: Context): View {
        Log.e("mixPlayer", "阿里播放器初始化...")
        aliPlayer = AliPlayerFactory.createAliPlayer(context.applicationContext)
        // 设置视频背景色 API
        aliPlayer.setVideoBackgroundColor(Color.BLACK)
        // 默认不能自动播放
        aliPlayer.isAutoPlay = false
        aliPlayer.setFastStart(true)
        aliPlayer.enableHardwareDecoder(VideoPlayerSPUtil.instance.isEnableHardDecoder)
        //播放配置设置
        // 多码率切换并自适应
        aliPlayer.selectTrack(TrackInfo.AUTO_SELECT_INDEX)
//        //获取当前渲染的帧率，数据类型为Float。
//        mAliyunRenderView.aliPlayer.getOption(IPlayer.Option.RenderFPS)
//        //获取当前播放的视频码率，数据类型为Float，单位为bps。
//        mAliyunRenderView.aliPlayer.getOption(IPlayer.Option.VideoBitrate)
//        //获取当前播放的音频码率，数据类型为Float，单位为bps。
//        mAliyunRenderView.aliPlayer.getOption(IPlayer.Option.AudioBitrate)
//        //获取当前的网络下行码率，数据类型为Float，单位为bps。
//        mAliyunRenderView.aliPlayer.getOption(IPlayer.Option.DownloadBitrate)
        val config = aliPlayer.config
        /** 配置网络相关 */
        // 设置referer，示例：http://example.aliyundoc.com。（注意：设置referer时，需要加上前面的协议部分。）
        // config.mReferrer = referrer
        // 设置用户代理
        // config.mUserAgent = "需要设置的UserAgent"
        // 设置网络超时时间，单位：毫秒
        config.mNetworkTimeout = 10000
        // 设置超时重试次数。每次重试间隔为networkTimeout。networkRetryCount=0则表示不重试，重试策略app决定，默认值为2
        config.mNetworkRetryCount = 2
        /** 配置缓存 */
        // 最大延迟。注意：直播有效。当延时比较大时，播放器sdk内部会追帧等，保证播放器的延时在这个范围内。
//        config.mMaxDelayTime = 1000
        // 三个缓冲区时长的大小关系必须为：mStartBufferDuration ≤ mHighBufferDuration ≤ mMaxBufferDuration。
        // 最大缓冲区时长。单位ms。播放器每次最多加载这么长时间的缓冲数据。缓存10分钟，使用大缓存
        config.mMaxBufferDuration = 1000 * 60 * 5
        // 高缓冲时长。单位ms。当网络不好导致加载数据时，如果加载的缓冲时长到达这个值，结束加载状态。
        config.mHighBufferDuration = 3000
        // 起播缓冲区时长。单位ms。这个时间设置越短，起播越快。也可能会导致播放之后很快就会进入加载状态。
        config.mStartBufferDuration = 500
        // 往前缓存的最大时长。单位ms。默认为0。
        config.mMaxBackwardBufferDurationMs = 0

//        // 设置 UserData
//        val userData = BaseScreenCastUtils.UserData
//        aliPlayer.userData = userData
//        // 支持投屏
//        config.mEnableProjection = true

        /**
         *  开启本地缓存，开启之后，会缓存到本地文件中。
         *  @param enable - 本地缓存功能开关。true：开启本地缓存，false：关闭，默认关闭。
         *  @param maxBufferMemoryKB - 新版本已废弃，暂无作用
         *  @param localCacheDir - 本地缓存的文件目录，为绝对路径。
         */
        val localCacheDir = PathUtils.getVideoCacheFile()
        if (!localCacheDir.exists()) {
            localCacheDir.mkdirs()
        }
        AliPlayerGlobalSettings.enableLocalCache(true, 1024 * 1024 * 2, localCacheDir.absolutePath)
        aliPlayer.config = config
        aliPlayer.scaleMode = ScaleMode.SCALE_TO_FILL
        // 设置渲染方式
        setSurfaceType(SurfaceType.TEXTURE_VIEW)
        initPlayerListener()
        return this
    }

    private fun initPlayerListener() {
        // mAliyunRenderView.setOnTrackReadyListenenr(com.aliyun.player.alivcplayerexpand.widget.AliyunVodPlayerView.VideoPlayerOnTrackReadyListenner(this))
//        //trackChange监听
//        mAliyunRenderView.setOnTrackChangedListener(com.aliyun.player.alivcplayerexpand.widget.AliyunVodPlayerView.VideoPlayerTrackChangedListener(this))
//        //字幕显示和隐藏
//        mAliyunRenderView.setOnSubtitleDisplayListener(com.aliyun.player.alivcplayerexpand.widget.AliyunVodPlayerView.VideoPlayerSubtitleDeisplayListener(this))
//        //seek结束事件
//        mAliyunRenderView.setOnSeekCompleteListener(com.aliyun.player.alivcplayerexpand.widget.AliyunVodPlayerView.VideoPlayerOnSeekCompleteListener(this))
//        //截图监听事件
//        mAliyunRenderView.setOnSnapShotListener(com.aliyun.player.alivcplayerexpand.widget.AliyunVodPlayerView.VideoPlayerOnSnapShotListener(this))
        aliPlayer.setOnInfoListener(OnAVPInfoListener(this))
        aliPlayer.setOnTrackReadyListener(OnAVPTrackReadyListener(this))
        aliPlayer.setOnErrorListener(OnAVPErrorListener(this))
        aliPlayer.setOnSnapShotListener(OnAVPSnapShotListener(this))
        aliPlayer.setOnPreparedListener(OnAVPPreparedListener(this))
        aliPlayer.setOnCompletionListener(OnAVPCompletionListener(this))
        aliPlayer.setOnTrackChangedListener(OnAVPTrackChangedListener(this))
        aliPlayer.setOnSeekCompleteListener(OnAVPSeekCompleteListener(this))
        aliPlayer.setOnVideoRenderedListener(OnAVPVideoRenderedListener(this))
        aliPlayer.setOnLoadingStatusListener(OnAVPLoadingStatusListener(this))
        aliPlayer.setOnRenderingStartListener(OnAVPRenderingStartListener(this))
        aliPlayer.setOnStateChangedListener(OnAVPStateChangedListener(this))
        aliPlayer.setOnSubtitleDisplayListener(OnAVPSubtitleDisplayListener(this))
        aliPlayer.setOnVideoSizeChangedListener(OnAVPVideoSizeChangedListener(this))
    }

    enum class SurfaceType {
        /**
         * TextureView
         */
        TEXTURE_VIEW,

        /**
         * SurfaceView
         */
        SURFACE_VIEW
    }

    /**
     * 该方法需要在创建播放器完成后,prepare前调用
     *
     * @param surfaceType Surface的类型
     */
    fun setSurfaceType(surfaceType: SurfaceType) {
        mIRenderView = if (surfaceType == SurfaceType.TEXTURE_VIEW) {
            TextureRenderView(context)
        } else {
            SurfaceRenderView(context)
        }
        mIRenderView?.addRenderCallback(MyRenderViewCallback(this))
        val layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
        addView(mIRenderView?.view, layoutParams)
    }



    /**
     * 设置播放源
     */
    fun setDataSource(url: String?) {
        val urlSource = UrlSource()
        urlSource.uri = url
        aliPlayer.setDataSource(urlSource)
    }


    /**
     * 设置是否静音
     */
    fun setMute(isMute: Boolean) {
        aliPlayer.isMute = isMute
    }

    /** 设置播放器地址的header */
    private fun setPlayUrlHeader(header: Map<*, *>?) {
        if (header == null || header.isEmpty()) return
        val size: Int = header.size
        val config = aliPlayer.config
        //定义header
        val headers = arrayOfNulls<String>(size)
        var index = 0
        for ((key, value) in header) {
            val keyStr = key.toString()
            val valueStr = value.toString()
            if ("Referer".equals(keyStr, true)) {
                config.mReferrer = valueStr
            } else if ("User-Agent".equals(keyStr, true)) {
                config.mUserAgent = valueStr
            } else {
                headers[index] = "$keyStr:$valueStr"
                index++
            }
        }
        if (headers.isNotEmpty()) {
            //设置header
            config.customHeaders = headers
        }
        aliPlayer.config = config
    }

    /**
     * 是否开启自动播放
     */
    override fun setAutoPlay(isAutoPlay: Boolean) {
        aliPlayer.isAutoPlay = isAutoPlay
    }

    /**
     * 设置播放速率
     */
    override fun setSpeed(speed: Float) {
        aliPlayer.speed = speed
    }

    override fun getSpeed(): Float {
        return aliPlayer.speed
    }


    /**
     * 是否循环播放
     */
    override fun setLoop(isLoop: Boolean) {
        aliPlayer.isLoop = isLoop
    }

    /**
     * 是否开启循环
     * @return true: 是 反之
     */

    override fun getLoop(): Boolean {
        return aliPlayer.isLoop
    }

    override fun getPlayerType(): Int {
        return PlayerType.ALIYUN
    }

    override fun setEnableHardDecoder(isEndableHardDecoder: Boolean) {
        aliPlayer.enableHardwareDecoder(VideoPlayerSPUtil.instance.isEnableHardDecoder)
    }


    /** 获取当前的网络下行码率，数据类型为Float，单位为bps。 */
    fun getDownloadBitrate(): Float {
        return aliPlayer.getOption(IPlayer.Option.DownloadBitrate).toString().toFloatOrNull() ?: 0f
    }

    /**
     * 截屏
     */
    fun snapshot() {
        aliPlayer.snapshot()
    }

    /**
     * 选择 track
     * @param index 索引
     */
    fun selectTrack(index: Int) {
        aliPlayer.selectTrack(index)
    }

    fun selectExtSubtitle(index: Int, selected: Boolean) {
        aliPlayer.selectExtSubtitle(index, selected)
    }

    /**
     * 选择 track
     * @param index 索引
     * @param focus 是否强制选择track
     */
    fun selectTrack(index: Int, focus: Boolean) {
        aliPlayer.selectTrack(index, focus)
    }

    /**
     * 停止播放
     */
    override fun stop() {
        aliPlayer.stop()
    }

    /**
     * prepare
     */
    fun prepare() {
        aliPlayer.prepare()
    }

    /**
     * 暂停播放,直播流不建议使用
     */
    override fun pause() {
        aliPlayer.pause()
    }

    override fun start() {
        aliPlayer.start()
    }

    /**
     * 重新加载
     */
    fun reload() {
        aliPlayer.reload()
    }


    /** 当前视频是否已准备完成 */
    override fun isPrepared(): Boolean {
        // error不算在prepared中
        return status in 2..6
    }

    /** 当前视频是否正在播放 */
    override fun isPlaying(): Boolean {
        return status == 3
    }

    /**
     * 获取视频时长
     */
    override fun getDuration(): Long {
        return if (isPrepared()) {
            aliPlayer.duration
        } else 0
    }

    override fun getCurrentPosition(): Long {
        return currentPosition
    }

    override fun getBufferedPosition(): Long {
        return bufferedPosition
    }

    override fun getCurrentDownloadSpeed(): Long {
        return currentDownloadSpeed
    }

    /**
     * seek
     *
     * @param position 目标位置
     * @param seekMode 精准/非精准seek
     */
    fun seekTo(position: Long, seekMode: SeekMode?) {
        aliPlayer.seekTo(position, seekMode)
    }

    /**
     * seek
     * 非精确
     * @param position 目标位置
     */
    override fun seekTo(seek: Long) {
        aliPlayer.seekTo(seek, SeekMode.Inaccurate)
    }

    /**
     * 获取播放器状态
     * @param status 状态
     */
    fun getPlayerStatus(): Int {
        return status
    }

    /**
     * 设置PlayerConfig
     */
    var playerConfig: PlayerConfig
        get() = aliPlayer.config
        set(playerConfig) {
            aliPlayer.config = playerConfig
        }

    /**
     * 设置缩放模式
     */
    override fun setScaleMode(model: Int) {
        aliPlayer.scaleMode = if (model == Constants.VIDEO_RESIZE_FILL) {
            ScaleMode.SCALE_TO_FILL
        } else {
            ScaleMode.SCALE_ASPECT_FIT
        }
    }

    /**
     * 获取当前缩放模式
     */

    override fun getScaleMode(): Int {
        return if (aliPlayer.scaleMode == ScaleMode.SCALE_TO_FILL) {
            Constants.VIDEO_RESIZE_FILL
        } else {
            Constants.VIDEO_RESIZE_FIT
        }
    }


    /**
     * 获取当前旋转模式
     */
    /**
     * 设置旋转模式
     */
    var rotateModel: RotateMode?
        get() = aliPlayer.rotateMode
        set(rotateModel) {
            aliPlayer.rotateMode = rotateModel
        }
    /**
     * 获取当前镜像模式
     */
    /**
     * 设置镜像模式
     */
    var mirrorMode: MirrorMode?
        get() = aliPlayer.mirrorMode
        set(mirrorMode) {
            aliPlayer.mirrorMode = mirrorMode
        }

    val mediaInfo: MediaInfo?
        get() = aliPlayer.mediaInfo

    /**
     * 软硬解开关
     *
     * @param enableHardwareDecoder true:硬解,false:软解
     */
    fun enableHardwareDecoder(enableHardwareDecoder: Boolean) {
        aliPlayer.enableHardwareDecoder(enableHardwareDecoder)
    }

    /**
     * 多码率时默认播放码率
     */
    fun setDefaultBandWidth(bandWidth: Int) {
        Log.e("abc : ", "setDefaultBandWidth: $bandWidth")
        aliPlayer.setDefaultBandWidth(bandWidth)
    }

    fun release() {
        stop()
        aliPlayer.setSurface(null)
        aliPlayer.release()
    }

    private class MyRenderViewCallback(aliyunRenderView: AliyunRenderView) : IRenderCallback {
        private val weakReference: WeakReference<AliyunRenderView>

        init {
            weakReference = WeakReference(aliyunRenderView)
        }

        override fun onSurfaceCreate(surface: Surface) {
            val aliyunRenderView = weakReference.get()
            aliyunRenderView?.aliPlayer?.setSurface(surface)
        }

        override fun onSurfaceChanged(width: Int, height: Int) {
            val aliyunRenderView = weakReference.get()
            aliyunRenderView?.aliPlayer?.surfaceChanged()
        }

        override fun onSurfaceDestroyed() {
            val aliyunRenderView = weakReference.get()
            aliyunRenderView?.aliPlayer?.setSurface(null)
        }
    }

    /**
     * OnPrepared
     */
    private class OnAVPPreparedListener(aliyunRenderView: AliyunRenderView) : IPlayer.OnPreparedListener {
        private val weakReference: WeakReference<AliyunRenderView>

        init {
            weakReference = WeakReference(aliyunRenderView)
        }

        override fun onPrepared() {
            val aliyunRenderView = weakReference.get()
            aliyunRenderView?.onPrepared()
        }
    }

    /**
     * 纯音频、纯视频流监听
     */
    interface OnVideoStreamTrackTypeListener {
        //纯视频
        fun onVideoOnlyType()

        //纯音频
        fun onAudioOnlyType()
    }


    fun setOnVideoStreamTrackType(listener: OnVideoStreamTrackTypeListener?) {
        mOnVideoStreamTrackTypeListener = listener
    }


    private fun onPrepared() {
        val trackVideo = aliPlayer.currentTrack(TrackInfo.Type.TYPE_VIDEO)
        val trackAudio = aliPlayer.currentTrack(TrackInfo.Type.TYPE_AUDIO)
        if (trackVideo == null && trackAudio != null) {
            mOnVideoStreamTrackTypeListener?.onAudioOnlyType()
        } else if (trackVideo != null && trackAudio == null) {
            mOnVideoStreamTrackTypeListener?.onVideoOnlyType()
        }

        mOnPreparedListener?.onPrepared()
    }

    /**
     * OnVideoRenderedListener
     */
    private class OnAVPVideoRenderedListener(aliyunRenderView: AliyunRenderView) : IPlayer.OnVideoRenderedListener {
        private val weakReference: WeakReference<AliyunRenderView>

        init {
            weakReference = WeakReference(aliyunRenderView)
        }

        override fun onVideoRendered(timeMs: Long, pts: Long) {
            val aliyunRenderView = weakReference.get()
            aliyunRenderView?.onVideoRendered(timeMs, pts)
        }
    }


    fun setOnVideoRenderedListener(listener: IPlayer.OnVideoRenderedListener?) {
        mOnVideoRenderedListener = listener
    }

    private fun onVideoRendered(timeMs: Long, pts: Long) {
        mOnVideoRenderedListener?.onVideoRendered(timeMs, pts)
    }

    /**
     * OnRenderingStartListener
     */
    private class OnAVPRenderingStartListener(aliyunRenderView: AliyunRenderView) : IPlayer.OnRenderingStartListener {
        private val weakReference: WeakReference<AliyunRenderView>

        init {
            weakReference = WeakReference(aliyunRenderView)
        }

        override fun onRenderingStart() {
            val aliyunRenderView = weakReference.get()
            aliyunRenderView?.onRenderingStart()
        }
    }

    private fun onRenderingStart() {
        mOnRenderingStartListener?.onRenderingStart()
    }

    /**
     * OnStateChangedListner
     */
    private class OnAVPStateChangedListener(aliyunRenderView: AliyunRenderView) : IPlayer.OnStateChangedListener {
        private val weakReference: WeakReference<AliyunRenderView>

        init {
            weakReference = WeakReference(aliyunRenderView)
        }

        override fun onStateChanged(i: Int) {
            val aliyunRenderView = weakReference.get()
            aliyunRenderView?.onStateChangedListener(i)
            aliyunRenderView?.status = i
        }
    }


    private fun onStateChangedListener(newState: Int) {
        mOnStateChangedListener?.onStateChanged(newState)
    }

    /**
     * OnVideoSizeChangedListener
     */
    private class OnAVPVideoSizeChangedListener(aliyunRenderView: AliyunRenderView) : IPlayer.OnVideoSizeChangedListener {
        private val weakReference: WeakReference<AliyunRenderView> = WeakReference(aliyunRenderView)
        override fun onVideoSizeChanged(width: Int, height: Int) {
            val aliyunRenderView = weakReference.get()
            aliyunRenderView?.onVideoSizeChanged(width, height)
        }
    }

    private var videoWidth = 0
    private var videoHeight = 0
    private fun onVideoSizeChanged(width: Int, height: Int) {
        if (videoWidth != width || videoHeight != height) {
            videoWidth = width
            videoHeight = height
            mOnVideoSizeChangedListener?.onVideoSizeChanged(videoWidth, videoHeight)
        }
    }

    /**
     * OnInfoListener
     */
    private class OnAVPInfoListener(aliyunRenderView: AliyunRenderView) : IPlayer.OnInfoListener {
        private val weakReference: WeakReference<AliyunRenderView>
        init {
            weakReference = WeakReference(aliyunRenderView)
        }
        override fun onInfo(infoBean: InfoBean) {
            val aliyunRenderView = weakReference.get()
            aliyunRenderView?.onInfo(infoBean)
        }
    }


    private fun onInfo(infoBean: InfoBean) {
        val value = infoBean.extraValue
        when (infoBean.code) {
            InfoCode.CurrentPosition -> { // 当前进度条
                currentPosition = value
                mOnInfoListener?.onInfo(Constants.INFO_CODE_CURRENT_POSITION, value)
            }

            InfoCode.BufferedPosition -> { // 缓冲进度
                bufferedPosition = value
                mOnInfoListener?.onInfo(Constants.INFO_CODE_BUFFERED_POSITION, value)
            }

            InfoCode.CurrentDownloadSpeed -> { // 当前下载速度
                currentDownloadSpeed = value
                mOnInfoListener?.onInfo(Constants.INFO_CODE_CURRENT_DOWNLOAD_SPEED, value)
            }
            else -> {}
        }

    }

    private class OnAVPTrackReadyListener(renderView: AliyunRenderView) : OnTrackReadyListener {
        private val mRenderViewWeakReference: WeakReference<AliyunRenderView>

        init {
            mRenderViewWeakReference = WeakReference(renderView)
        }

        override fun onTrackReady(mediaInfo: MediaInfo) {
            val aliyunRenderView = mRenderViewWeakReference.get()
            aliyunRenderView?.onTrackReady(mediaInfo)
        }
    }


    fun setOnTrackReadyListener(listener: OnTrackReadyListener?) {
        mOnTrackReadyListener = listener
    }

    private fun onTrackReady(mediaInfo: MediaInfo) {
        mOnTrackReadyListener?.onTrackReady(mediaInfo)
    }

    /**
     * OnLoadingStatusListener
     */
    private class OnAVPLoadingStatusListener(aliyunRenderView: AliyunRenderView) : IPlayer.OnLoadingStatusListener {
        private val weakReference: WeakReference<AliyunRenderView>

        init {
            weakReference = WeakReference(aliyunRenderView)
        }

        override fun onLoadingBegin() {
            val aliyunRenderView = weakReference.get()
            aliyunRenderView?.onLoadingBegin()
        }

        override fun onLoadingProgress(percent: Int, netSpeed: Float) {
            val aliyunRenderView = weakReference.get()
            aliyunRenderView?.onLoadingProgress(percent, netSpeed)
        }

        override fun onLoadingEnd() {
            val aliyunRenderView = weakReference.get()
            aliyunRenderView?.onLoadingEnd()
        }
    }


    private fun onLoadingBegin() {
        mOnLoadingStatusListener?.onLoadingBegin()
    }

    private fun onLoadingProgress(percent: Int, netSpeed: Float) {
        mOnLoadingStatusListener?.onLoadingProgress(percent, netSpeed)
    }

    private fun onLoadingEnd() {
        mOnLoadingStatusListener?.onLoadingEnd()
    }

    /**
     * OnSnapShotListener
     */
    private class OnAVPSnapShotListener(aliyunRenderView: AliyunRenderView) : OnSnapShotListener {
        private val weakReference: WeakReference<AliyunRenderView>

        init {
            weakReference = WeakReference(aliyunRenderView)
        }

        override fun onSnapShot(bitmap: Bitmap, with: Int, height: Int) {
            val aliyunRenderView = weakReference.get()
            aliyunRenderView?.onSnapShot(bitmap, with, height)
        }
    }


    fun setOnSnapShotListener(listener: OnSnapShotListener?) {
        mOnSnapShotListener = listener
    }

    private fun onSnapShot(bitmap: Bitmap, with: Int, height: Int) {
        mOnSnapShotListener?.onSnapShot(bitmap, with, height)
    }

    /**
     * OnCompletionListener
     */
    private class OnAVPCompletionListener(aliyunRenderView: AliyunRenderView) : IPlayer.OnCompletionListener {
        private val weakReference: WeakReference<AliyunRenderView>

        init {
            weakReference = WeakReference(aliyunRenderView)
        }

        override fun onCompletion() {
            val aliyunRenderView = weakReference.get()
            aliyunRenderView?.onCompletion()
        }
    }


    private fun onCompletion() {
        mOnCompletionListener?.onCompletion()
    }

    /**
     * OnSeekCompleteListener
     */
    private class OnAVPSeekCompleteListener(aliyunRenderView: AliyunRenderView) : IPlayer.OnSeekCompleteListener {
        private val weakReference: WeakReference<AliyunRenderView>

        init {
            weakReference = WeakReference(aliyunRenderView)
        }

        override fun onSeekComplete() {
            val aliyunRenderView = weakReference.get()
            aliyunRenderView?.onSeekComplete()
        }
    }


    fun setOnSeekCompleteListener(listener: IPlayer.OnSeekCompleteListener?) {
        mOnSeekCompleteListener = listener
    }

    private fun onSeekComplete() {
        if (mOnSeekCompleteListener != null) {
            mOnSeekCompleteListener?.onSeekComplete()
        }
    }

    /**
     * OnTrackChangedListener
     */
    private class OnAVPTrackChangedListener(aliyunRenderView: AliyunRenderView) : OnTrackChangedListener {
        private val weakReference: WeakReference<AliyunRenderView>

        init {
            weakReference = WeakReference(aliyunRenderView)
        }

        override fun onChangedSuccess(trackInfo: TrackInfo) {
            val aliyunRenderView = weakReference.get()
            aliyunRenderView?.onChangedSuccess(trackInfo)
        }

        override fun onChangedFail(trackInfo: TrackInfo, errorInfo: ErrorInfo) {
            val aliyunRenderView = weakReference.get()
            aliyunRenderView?.onChangedFail(trackInfo, errorInfo)
        }
    }


    fun setOnTrackChangedListener(listener: OnTrackChangedListener?) {
        mOnTrackChangedListener = listener
    }

    private fun onChangedSuccess(trackInfo: TrackInfo) {
        mOnTrackChangedListener?.onChangedSuccess(trackInfo)
    }

    private fun onChangedFail(trackInfo: TrackInfo, errorInfo: ErrorInfo) {
        mOnTrackChangedListener?.onChangedFail(trackInfo, errorInfo)
    }

    /**
     * OnErrorListener
     */
    private class OnAVPErrorListener(aliyunRenderView: AliyunRenderView) : IPlayer.OnErrorListener {
        private val weakReference: WeakReference<AliyunRenderView>

        init {
            weakReference = WeakReference(aliyunRenderView)
        }

        override fun onError(errorInfo: ErrorInfo) {
            val aliyunRenderView = weakReference.get()
            aliyunRenderView?.onError(errorInfo)
        }
    }


    private fun onError(errorInfo: ErrorInfo) {
        mOnErrorListener?.onError(errorInfo.code.toString())
    }

    /**
     * onSubtitleDisplayListener
     */
    private class OnAVPSubtitleDisplayListener(aliyunRenderView: AliyunRenderView) : OnSubtitleDisplayListener {
        private val weakReference: WeakReference<AliyunRenderView>

        init {
            weakReference = WeakReference(aliyunRenderView)
        }

        override fun onSubtitleExtAdded(trackIndex: Int, url: String) {
            val aliyunRenderView = weakReference.get()
            aliyunRenderView?.onSubtitleExtAdded(trackIndex, url)
        }

        override fun onSubtitleShow(trackIndex: Int, id: Long, data: String) {
            val aliyunRenderView = weakReference.get()
            aliyunRenderView?.onSubtitleShow(trackIndex, id, data)
        }

        override fun onSubtitleHide(trackIndex: Int, id: Long) {
            val aliyunRenderView = weakReference.get()
            aliyunRenderView?.onSubtitleHide(trackIndex, id)
        }

        override fun onSubtitleHeader(index: Int, data: String) {
            val aliyunRenderView = weakReference.get()
            aliyunRenderView?.oSubtitleHeader(index, data)
        }
    }

    private fun oSubtitleHeader(index: Int, data: String) {
        mOnSubtitleDisplayListener?.onSubtitleHeader(index, data)
    }

    private fun onSubtitleHide(trackIndex: Int, id: Long) {
        mOnSubtitleDisplayListener?.onSubtitleHide(trackIndex, id)
    }

    private fun onSubtitleShow(trackIndex: Int, id: Long, data: String) {
        mOnSubtitleDisplayListener?.onSubtitleShow(trackIndex, id, data)
    }

    private fun onSubtitleExtAdded(trackIndex: Int, url: String) {
        mOnSubtitleDisplayListener?.onSubtitleExtAdded(trackIndex, url)
    }


    fun setOnSubtitleDisplayListener(listener: OnSubtitleDisplayListener?) {
        mOnSubtitleDisplayListener = listener
    }


    override fun onVodInit(vararg init: Any?): Boolean {
        // 处在播放状态，停止视频
        if (init.isEmpty() || init.size < 2) return false
        // 获取播放地址
        val url = init[0] as String
        // 设置起播时间
        startPosition = init[1] as Long
        var headerMap: Map<*, *>? = null
        if (init.size >= 3) {
            headerMap = init[2] as Map<*, *>?
        }
        // 设置播放地址的header
        setPlayUrlHeader(headerMap)
        // 设置播放器
        setDataSource(url)
        // 准备读取并解析数据
        prepare()
        return false
    }

    override fun onVodPrepared(vararg prepared: Any) {

    }

    override fun onVodStart() {
        // 定位到起播为止
        if (isPlaying()) return
        if (startPosition > 0) {
            seekTo(startPosition)
            currentPosition = startPosition
        }
        start()
        startPosition = -1
    }

    override fun onVodFirstFrameStart() {

    }

    override fun onVodSwitchDisplayControlView() {

    }

    override fun onVodPause() {
        pause()
    }

    override fun onVodStop() {
        startPosition = -1
        currentPosition = 0
        stop()
    }

    override fun onVodError(vararg params: Any) {
        startPosition = -1
        currentPosition = 0
    }

    override fun onVodComplete() {
        // 无需处理
        startPosition = -1
        currentPosition = 0
    }

    override fun onVodRelease() {
        release()
        status = 0
        startPosition = -1
        mIRenderView = null
        currentPosition = 0
    }

    override fun onVodLockedScreen(vararg params: Any) {

    }

    override fun onVodFullScreen(vararg params: Any) {

    }

    override fun onVodLoadingBegin() {

    }

    override fun onVodLoadingProgress(vararg params: Any) {

    }

    override fun onVodLoadingEnd() {

    }

    override fun onVodBackPress(): Boolean {
        return false
    }

    override fun onEpisodeSelected() {
    }

    override fun onVodShowUnlockUI(isDisplayUI: Boolean) {
        if (isDisplayUI && isPlaying()) {
            stop()
        }
    }

    override fun onVodSkits() {

    }


    override fun setOnErrorListener(listener: OnErrorListener) {
        mOnErrorListener = listener
    }

    override fun setOnInfoListener(listener: OnInfoListener) {
        mOnInfoListener = listener
    }

    override fun setOnPreparedListener(listener: OnPreparedListener) {
        mOnPreparedListener = listener
    }

    override fun setOnCompletionListener(listener: OnCompletionListener) {
        mOnCompletionListener = listener
    }

    override fun setOnStateChangedListener(listener: OnStateChangedListener) {
        mOnStateChangedListener = listener
    }

    override fun setOnLoadingStatusListener(listener: OnLoadingStatusListener) {
        mOnLoadingStatusListener = listener
    }

    override fun setOnRenderingStartListener(listener: OnRenderingStartListener) {
        mOnRenderingStartListener = listener
    }

    override fun setOnVideoSizeChangedListener(listener: OnVideoSizeChangedListener) {
        mOnVideoSizeChangedListener = listener
    }
}